package broker

import (
	"errors"
	"fmt"
	database "hft/Database"
	"hft/Database/admin"
	"hft/Database/admin/common_phrase"
	"hft/Database/admin/file"
	"hft/Database/admin/loupan_db"
	"hft/Http/Models/dao"
	"hft/Http/Models/request"
	"hft/Http/Services/base"
	"hft/Http/Services/broker/broker_dao"
	"hft/Http/Services/broker/broker_utils"
	utils "hft/Http/Utils"
	"hft/e"
	"hft/global"
	"hft/tools"
	"regexp"

	"gorm.io/gorm"
)

type Broker struct{}

// 获取经纪人列表
func (*Broker) GetBrokerList(claims tools.BaseClaims, paginate *request.BrokerPage) (data *utils.Page, err error) {
	var brokers = make([]*admin.Account, 0)
	account, err := base.FindAccount(claims, global.OC_DB)
	if err != nil {
		return nil, errors.New(e.AccountNotExist)
	}
	global.OC_DB.Scopes(dao.BrokerDao.GetBrokerList(paginate, account.RegionLink, fmt.Sprintf("%v%v,", account.AccountLink, account.ID), global.OC_DB)).Find(&brokers).Offset(-1).Limit(-1).Count(&paginate.Total)
	for _, v := range brokers {
		v.Avatar = global.OC_CONFIG.AliyunOSS.BucketUrl + v.Avatar
	}
	paginate.Data = brokers
	return &paginate.Page, nil
}

func (*Broker) CreateBroker(data *admin.Account, claims tools.BaseClaims) (err error) {
	var role *admin.Role
	account, err := base.FindAccount(claims, global.OC_DB)
	if err != nil {
		return err
	}
	global.OC_DB.First(&role, 33)
	if res1, err1 := tools.ValidIDCard(data.IDCard, data.RealName); res1.Data.ResponseCode != "0" {
		return errors.New(e.IDCardNotPass)
	} else if err1 != nil {
		return errors.New(e.ErrorInfo)
	}
	fmt.Println("13")
	data = broker_utils.OperaData(data, role, account)
	err = global.OC_DB.Transaction(func(tx *gorm.DB) error {
		data.Belong = account.Belong
		res := tx.Where("username = ?", data.Username).FirstOrCreate(&data)
		if res.Error != nil {
			return errors.New(e.ErrorInfo)
		} else if res.RowsAffected == 0 {
			return errors.New(e.AccountHasExit)
		}
		var newUser *admin.Account
		err := tx.Where("username = ?", data.Username).First(&newUser).Error
		if err != nil {
			return errors.New(e.AccountNotExist)
		}
		var newAccountExpand = &admin.AccountExpand{
			AccountId: int(newUser.ID),
			Score:     1,
			IsAudit:   1,
			Base:      database.Base{Sort: 1},
		}
		err = tx.Create(&newAccountExpand).Error
		if err != nil {
			return errors.New(e.ErrorInfo)
		}
		// if err = broker_dao.BindLouPanPhone(tx, data.LouPan, data.Phone, account.Phone); err != nil { // 绑定分机号
		// 	return err
		// }
		var newAccounta *admin.Account
		err = tx.Select("username,id").Where("username = ?", account.Username).First(&newAccounta).Error
		if err != nil {
			return errors.New(e.AccountNotExist)
		}
		var dir = &file.Dir{
			AccountID: newAccounta.ID,
			Link:      ",",
		}
		err = tx.Create(&dir).Error
		if err != nil {
			return errors.New(e.ErrorInfo)
		}
		// 创建模板
		var modCateList = make([]*common_phrase.CommonPhraseCate, 0)
		tx.Where("can_edit = ?", 1).Find(&modCateList)
		var ids []int
		for _, v := range modCateList {
			ids = append(ids, int(v.ID))
		}
		var modList = make([]*common_phrase.CommonPhrase, 0)
		tx.Where("category IN ?", ids).Find(&modList)
		var chatModUsual []*common_phrase.CommonPhraseUsual
		for _, v := range modList {
			chatModUsual = append(chatModUsual, &common_phrase.CommonPhraseUsual{
				CategoryID: uint(v.CategoryID),
				ChatText:   v.ChatText,
				AccountID:  int(data.ID),
			})
		}
		tx.Create(&chatModUsual)
		return nil
	})

	return err

}

func (*Broker) EditBroker(data *admin.Account, claims tools.BaseClaims) (err error) {
	account, err := base.FindAccount(claims, global.OC_DB)
	if err != nil {
		return err
	}
	var role *admin.Role

	if err = global.OC_DB.First(&role, 33).Error; err != nil {
		return errors.New(e.RoleNotExist)
	}
	var broker *admin.Account
	if err = global.OC_DB.First(&broker, data.ID).Error; err != nil {
		return errors.New(e.AccountNotExist)
	}
	if ok := broker_utils.CanOperaThisAccount(fmt.Sprintf("%v%v", account.AccountLink, account.ID), fmt.Sprintf("%v%v", broker.AccountLink, broker.ID)); !ok {
		return errors.New(e.NoRightToOpera)
	}
	global.OC_DB.Transaction(func(tx *gorm.DB) error {
		if res := tx.Model(&admin.Account{}).Where("id = ?", data.ID).Updates(map[string]interface{}{
			"avatar":    broker_utils.RemovePrefix(data.Avatar, global.OC_CONFIG.AliyunOSS.BucketUrl),
			"id_card":   data.IDCard,
			"real_name": data.RealName,
		}); res.RowsAffected == 0 {
			return errors.New(e.AccountNotExist)
		} else if res.Error != nil {
			return errors.New(e.ErrorInfo)
		}
		if err := broker_dao.BindLouPanPhone(tx, data.LouPan, broker.Phone, account.Phone); err != nil {
			return err
		}
		// 添加楼盘
		tx.Model(&broker).Association("LouPan").Replace(&data.LouPan)
		return nil
	})

	return nil

}

func (*Broker) ReplaceLouPan(accountId int, ids []int, claims tools.BaseClaims) (err error) {

	var account *admin.Account

	var louPans []*admin.LouPan

	var broker *admin.Account

	err = global.OC_DB.Scopes(dao.ParseAccountDao.Parse(claims, global.OC_DB)).First(&account).Error

	if err != nil {
		return errors.New("无该账号信息")
	}

	err = global.OC_DB.First(&broker, accountId).Error

	if err != nil {
		return errors.New("未知错误500")
	}

	match, _ := regexp.MatchString(fmt.Sprintf("^%v", account.AccountLink), broker.AccountLink)

	if !match {
		return errors.New("你无权修改该经纪人配置")
	}

	err = global.OC_DB.Where("region_link REGEXP ?", account.RegionLink).Find(&louPans, ids).Error

	if err != nil {
		return errors.New("未知错误500")
	}

	global.OC_DB.Model(&broker).Association("LouPan").Replace(louPans)

	return nil
}

// 获取当前所有楼盘名称
func (*Broker) GetAllLouPan(request *request.SearchLou, claims tools.BaseClaims) (list []*admin.LouPan, err error) {

	var account *admin.Account

	err = global.OC_DB.Scopes(dao.ParseAccountDao.Parse(claims, global.OC_DB)).First(&account).Error

	if err != nil {
		return nil, errors.New("账号信息不存在")
	}

	var lous []*admin.LouPan

	name := utils.DeleteStringSpace(request.Name)

	global.OC_DB.Scopes(dao.BrokerDao.GetAllLouPan(name, account.RegionLink, global.OC_DB)).Preload("SellLouPanInfo").Find(&lous)

	return lous, nil
}

func (*Broker) Delete(ids []int, claims tools.BaseClaims) (err error) {

	ManagerAccount, err := base.FindAccount(claims, global.OC_DB)
	if err != nil {
		return err
	}
	var accountList []*admin.Account
	global.OC_DB.Find(&accountList, ids)
	if ok := utils.IsBelongThisAccount(accountList, ManagerAccount); !ok {
		return errors.New(e.NoRightToOpera)
	}
	// // 清除经纪人的目的码记录
	// err = global.OC_DB.Transaction(func(tx *gorm.DB) error {
	// 	if err := broker_dao.ClearPhone(tx,)
	// })
	err = global.OC_DB.Model(&admin.Account{}).Unscoped().Delete(&accountList).Error
	if err != nil {
		return errors.New("未知错误500")
	}
	return nil

}

func (*Broker) Status(broker *admin.Account, claims tools.BaseClaims) (err error) {
	var nowStatus = broker_utils.ChangeStatus(broker.Status)
	account, err := base.FindAccount(claims, global.OC_DB)
	if err != nil {
		return err
	}
	if err = global.OC_DB.First(&broker, broker.ID).Error; err != nil {
		return errors.New(e.AccountNotExist)
	}
	if match, _ := regexp.MatchString(fmt.Sprintf("^%v", account.RegionLink), broker.RegionLink); !match {
		return errors.New(e.NoRightToOpera)
	}
	fmt.Println(nowStatus)
	global.OC_DB.Model(&admin.Account{}).Where("id = ?", broker.ID).Update("status", nowStatus)
	return nil

}

func (*Broker) SendGold(ID int, Num int64, claims tools.BaseClaims) (err error) {

	var account *admin.Account

	err = global.OC_DB.Scopes(dao.ParseAccountDao.Parse(claims, global.OC_DB)).First(&account).Error

	if err != nil {
		return errors.New("找不到该账号信息")
	}

	var broker *admin.Account

	err = global.OC_DB.Preload("AccountExpand").First(&broker, ID).Error

	if err != nil {
		return errors.New("该经纪人不存在")
	}

	match, _ := regexp.MatchString(fmt.Sprintf("^%v", account.AccountLink), broker.AccountLink)

	if !match {
		return errors.New("你无权给改经纪人赠送金币")
	}

	var nowGold = broker.AccountExpand.Score + uint(Num)

	err = global.OC_DB.Transaction(func(tx *gorm.DB) error {
		err = tx.Model(&admin.AccountExpand{}).Where("account_id = ?", broker.ID).Update("score", nowGold).Error

		if err != nil {
			return errors.New("超出最大金币范围，请让经纪人尽快使用金币")
		}

		var gold = &loupan_db.AccountLouPanDb{
			Describe:       "赠送金币",
			AccountID:      broker.ID,
			Amount:         uint(Num),
			Gain:           true,
			OriginalAmount: broker.AccountExpand.Score,
		}
		err = tx.Create(&gold).Error
		if err != nil {
			return errors.New(e.ErrorInfo)
		}
		return nil
	})

	return err
}

var BrokerService = new(Broker)
